package org.darcy.service.check.impl;

import java.util.Date;
import java.util.List;

import org.darcy.dao.CheckDeliveryMapper;
import org.darcy.entity.CheckDelivery;
import org.darcy.entity.business.BusinessContract;
import org.darcy.entity.business.BusinessFinancialReceived;
import org.darcy.entity.check.ContractRequirement;
import org.darcy.entity.check.ExtInfo;
import org.darcy.entity.org.Staff;
import org.darcy.framework.constant.SysConstant;
import org.darcy.framework.generic.GenericServiceImpl;
import org.darcy.framework.model.PageData;
import org.darcy.framework.model.PageParam;
import org.darcy.service.business.BusinessContractService;
import org.darcy.service.business.BusinessFinancialReceivedService;
import org.darcy.service.check.CheckDeliveryService;
import org.darcy.service.privilege.SysUserService;
import org.darcy.service.sys.SysFileService;
import org.darcy.service.work.WorkService;
import org.darcy.utils.UserTool;
import org.darcy.vo.ContractAmount;
import org.darcy.vo.project.CapitalItem;
import org.darcy.vo.project.CapitalSummary;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;

/**
 * CheckDelivery服务实现
 */
@Service
public class CheckDeliveryServiceImpl extends GenericServiceImpl<CheckDelivery> implements CheckDeliveryService {

	@Autowired
	private CheckDeliveryMapper mapper;

	@Autowired
	private WorkService WorkService;

	@Autowired
	@Lazy
	private BusinessContractService BusinessContractService;

	@Autowired
	@Lazy
	private BusinessFinancialReceivedService BusinessFinancialReceivedService;

	@Autowired
	private SysUserService SysUserService;

	@Autowired
	@Lazy
	private SysFileService SysFileService;

	/**
	 * 处理json信息
	 */
	private void processData(CheckDelivery record) {
		// 处理附件
		if (record.getConfirmFileList() != null && !record.getConfirmFileList().isEmpty()) {
			String file = SysFileService.getFileIdList(record.getConfirmFileList());
			record.setConfirmFile(file);
		}
		// 处理合同特殊要求
		List<ContractRequirement> contractRequirementList = record.getContractRequirementList();
		if (contractRequirementList != null) {
			float otherTotal = 0f;
			for (ContractRequirement a : contractRequirementList) {
				if (a.getType().equals("专家费")) {
					record.setSpecialistFee(a.getAmount());
				} else {
					otherTotal += a.getAmount();
				}
			}
			record.setOutsourceFee(otherTotal);
			record.setContractRequirement(JSONUtil.toJsonStr(contractRequirementList));
		}

		record.setExtInfo(JSONUtil.toJsonStr(record.getExtInfoList()));
	}

	/**
	 * 处理工作任务
	 * 
	 * @param param 前端传入的派工单
	 */
	private void processWork(CheckDelivery param) {
		CheckDelivery record = this.getById(param.getId());
		BusinessContract contract = BusinessContractService.getById(record.getContractId());
		record.setContract(contract);

		String name = SysUserService.getById(contract.getProjectOperator()).getRealName();
		contract.setProjectOperatorName(name);

		String title = String.format("[%s]的%s", UserTool.getLoginUser().getRealName(), "派工单");
		String date = DateUtil.format(record.getContract().getCreateTime(), "yyyy-MM-dd");
		String summary = String.format("合同编号：%s\n合同类型：%s\n委托日期：%s\n负责人：%s", record.getContract().getFormNo(),
				record.getContract().getProjectType(), date, record.getContract().getProjectOperatorName());
		WorkService.addWorkTask(param, title, summary, SysConstant.FormType.CheckDelivery);
	}

	@Override
	public CheckDelivery insert(CheckDelivery record) {
		processData(record);
		record.setCreateTime(new Date());
		// 编号处理
		String time = DateUtil.format(record.getCreateTime(), DatePattern.PURE_DATETIME_FORMATTER);
		record.setFormNo("PGD" + time);
		super.insert(record);
		// 因为派工单的生成由合同审批通过自动触发，因此这里不再生成工作流事项
		// processWork(record, 0);
		return record;
	}

	/**
	 * 派工单的提交需要满足以下任一条件， 1：派工单的收款金额比例大于合同的派工到账比例 2：审批人是总经办人员
	 */
	private boolean isValid(CheckDelivery record) {
		Integer contractId = this.getById(record.getId()).getContractId();
		float total = 0f;// 收款总金额
		List<BusinessFinancialReceived> list = BusinessFinancialReceivedService.getList(contractId);
		for (BusinessFinancialReceived a : list) {
			if (a.getPayAmount() == null) {
				continue;
			}
			// 处理收款金额
			List<ContractAmount> amountList = JSONUtil.parseArray(a.getPayDetail()).toList(ContractAmount.class);
			for (ContractAmount b : amountList) {
				if (b.getName().equals(record.getItemName())) {
					total += b.getValue();
				}
			}
		}
		float ratio1 = 0f; // 收款比例
		if (record.getItemCapital() != null && record.getItemCapital() != 0) {
			ratio1 = 100 * total / record.getItemCapital();
		}

		float ratio2 = 0f;// 合同派工比例
		// 取合同中派工比例
		BusinessContract contract = BusinessContractService.getById(contractId);
		List<ContractAmount> ratioList = JSONUtil.parseArray(contract.getContractRatio()).toList(ContractAmount.class);
		for (ContractAmount a : ratioList) {
			if (a.getName().equals(record.getItemName())) {
				ratio2 = a.getValue();
				break;
			}
		}

		if (ratio1 >= ratio2) {
			return true;
		} else {
			Staff staff = record.getAaList().get(0);
			// 101~104是总经办人员
			if (staff.getUid() < 105) {
				return true;
			}
		}
		return false;
	}

	@Override
	public CheckDelivery updateFlow(CheckDelivery record) {
		processData(record);
		super.update(record);
		if (record.getIsCommit()) {
			if (isValid(record)) {
				processWork(record);
			} else {
				record.setIsCommit(false);
			}
		}
		return record;
	}

	@Override
	public CheckDelivery getDetail(Integer id) {
		CheckDelivery record = this.getById(id);
		BusinessContract contract = BusinessContractService.getDetail(record.getContractId());
		record.setContract(contract);
		record.setContractRequirementList(JSONUtil.toList(record.getContractRequirement(), ContractRequirement.class));
		record.setExtInfoList(JSONUtil.toList(record.getExtInfo(), ExtInfo.class));
		float businessTotal = 0f;
		for(ExtInfo a: record.getExtInfoList()) {
			businessTotal += a.getAmount();
		}
		record.setBusinessTotal(businessTotal);
		record.setContractTotal(businessTotal + record.getSpecialistFee());

		if (record.getProjectManager() != null) {
			String name = SysUserService.getById(record.getProjectManager()).getRealName();
			record.setProjectManagerName(name);
		}
		// 文件处理
		if (StrUtil.isNotEmpty(record.getConfirmFile())) {
			record.setConfirmFileList(SysFileService.getFilePathList(record.getConfirmFile()));
		}
		if (StrUtil.isNotEmpty(record.getReportFile())) {
			record.setReportFileList(SysFileService.getFilePathList(record.getReportFile()));
		}
		if (StrUtil.isNotEmpty(record.getPublishPic())) {
			record.setPublishPicList(SysFileService.getFilePathList(record.getPublishPic()));
		}
		if (StrUtil.isNotEmpty(record.getArchiveFile())) {
			record.setArchiveFileList(SysFileService.getFilePathList(record.getArchiveFile()));
		}

		WorkService.processWorkFlowObject(record, SysConstant.FormType.CheckDelivery);
		return record;
	}

	@Override
	public PageData<CheckDelivery> page(PageParam<CheckDelivery> param) {
		IPage<CheckDelivery> queryPage = new Page<CheckDelivery>(param.getQuery().getPageNum(),
				param.getQuery().getPageSize());
		IPage<CheckDelivery> data = mapper.getPage(queryPage, param.getEntity());
		for (CheckDelivery a : data.getRecords()) {
			if (a.getWork() != null)
				a.getWork().setStatusName(a.getWork().fetchStatusName());
		}
		PageData<CheckDelivery> pageData = new PageData<CheckDelivery>(data, param);
		return pageData;
	}

	@Override
	public List<CheckDelivery> getList(Integer contractId) {
		QueryWrapper<CheckDelivery> q = new QueryWrapper<CheckDelivery>();
		q.eq("contract_id", contractId);
		return this.getList(q);
	}

	@Override
	public List<CapitalItem> getCapitalSummary(CapitalSummary param) {
		List<CapitalItem> list = mapper.getCapitalSummary(param);
		return list;
	}

	@Override
	public int archive(Integer id) {
		CheckDelivery record = this.getById(id);
		// 派工单
		List<CheckDelivery> deliveryList = this.getList(record.getContractId());
		boolean isFinished = true;
		for (CheckDelivery a : deliveryList) {
			if (a.getArchiveNo() == null) {
				isFinished = false;
			}
		}
		// 项目状态改为已完成
		if (isFinished) {
			BusinessContract contract = new BusinessContract();
			contract.setId(record.getContractId());
			contract.setProjectStatus(SysConstant.ProjectStatus.STATUS_DONE);
			BusinessContractService.update(contract);
		}
		return 0;
	}

}
